package org.zjx.core;

import com.sun.jna.platform.win32.WinDef;
import lombok.Data;
import org.zjx.command.ICommand;
import org.zjx.command.basic.ScreenshotCommand;
import org.zjx.command.basic.WaitCommand;
import org.zjx.enums.GameStatus;
import org.zjx.enums.WindowState;
import org.zjx.manager.WindowPool;
import org.zjx.strategy.IGameStrategy;
import org.zjx.strategy.StrategyFactory;
import org.zjx.util.HwndUtil;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;

@Data
public class GameWindow implements IWindow, Runnable {
    private final String id;
    private final WinDef.HWND hwnd;
    private GameStatus gameStatus;
    private WindowState windowState = WindowState.OCCLUDED;
    private WindowSession currentSession;

    // 自动化相关字段
    private volatile boolean automationEnabled = false;
    private long automationIntervalMs = 1000;
    private Thread automationThread;
    private final AtomicBoolean automationRunning = new AtomicBoolean(false);

    // 策略工厂
    private StrategyFactory strategyFactory;

    // 外部策略函数（备用）
    private Function<Image, ICommand> customAnalysisStrategy;

    // 窗口任务（由外部设置）
    private Runnable currentTask;

    public GameWindow(WinDef.HWND hwnd, String windowTitle) {
        this.hwnd = hwnd;
        this.id = windowTitle != null ? windowTitle :
                "Window-" + System.currentTimeMillis() + "-" + (hwnd != null ? hwnd.hashCode() : "NULL");
    }

    /**
     * 设置策略工厂
     */
    public void setStrategyFactory(StrategyFactory factory) {
        this.strategyFactory = factory;
        System.out.println("[GameWindow] Strategy factory set for: " + id);
    }

    /**
     * 获取策略工厂（如未设置则创建默认工厂）
     */
    public StrategyFactory getStrategyFactory() {
        if (strategyFactory == null) {
            strategyFactory = new StrategyFactory();
            System.out.println("[GameWindow] Created default strategy factory for: " + id);
        }
        return strategyFactory;
    }

    /**
     * 设置自定义分析策略（覆盖策略工厂）
     */
    public void setCustomAnalysisStrategy(Function<Image, ICommand> strategy) {
        this.customAnalysisStrategy = strategy;
        System.out.println("[GameWindow] Custom analysis strategy set for: " + id);
    }

    /**
     * 启动自动化（使用策略工厂）
     */
    public void startAutomation(long intervalMs) {
        startAutomationWithFactory(intervalMs);
    }

    /**
     * 启动自动化（使用策略工厂）
     */
    public void startAutomationWithFactory(long intervalMs) {
        if (automationRunning.get()) {
            System.out.println("[GameWindow] Automation already running for: " + id);
            return;
        }

        this.automationIntervalMs = intervalMs;
        automationEnabled = true;
        automationRunning.set(true);

        automationThread = new Thread(this, "Automation-" + id);
        automationThread.setDaemon(true);
        automationThread.start();

        System.out.println("[GameWindow] Automation started for: " + id + " (interval: " + intervalMs + "ms)");
    }

    /**
     * 启动自动化（使用自定义策略）
     */
    public void startAutomationWithCustomStrategy(Function<Image, ICommand> strategy, long intervalMs) {
        setCustomAnalysisStrategy(strategy);
        startAutomationWithFactory(intervalMs);
    }

    /**
     * 自动化主循环
     */
    @Override
    public void run() {
        System.out.println("[GameWindow] Automation loop started for: " + id);

        while (automationRunning.get()) {
            try {
                // 1. 截图
                ScreenshotCommand screenshotCmd = new ScreenshotCommand(this);
                screenshotCmd.execute();
                Image screenshot = screenshotCmd.getScreenshot();

                if (screenshot == null) {
                    Thread.sleep(automationIntervalMs);
                    continue;
                }

                // 2. 分析并生成指令
                ICommand nextCommand = analyzeScreenshot(screenshot);

                // 3. 执行指令
                if (nextCommand != null) {
                    boolean submitted = submitCommand(nextCommand);
                    if (submitted) {
                        System.out.println("[Automation] Executed: " + nextCommand.getCommandName());
                    }
                }

                Thread.sleep(automationIntervalMs);

            } catch (InterruptedException e) {
                if (automationRunning.get()) {
                    System.out.println("[GameWindow] Automation interrupted for: " + id);
                }
                break;
            } catch (Exception e) {
                System.err.println("[GameWindow] Automation error for " + id + ": " + e.getMessage());
                try {
                    Thread.sleep(automationIntervalMs * 2);
                } catch (InterruptedException ie) {
                    break;
                }
            }
        }

        System.out.println("[GameWindow] Automation loop stopped for: " + id);
    }

    /**
     * 截图分析逻辑
     */
    protected ICommand analyzeScreenshot(Image screenshot) {
        // 优先使用自定义策略
        if (customAnalysisStrategy != null) {
            try {
                return customAnalysisStrategy.apply(screenshot);
            } catch (Exception e) {
                System.err.println("[GameWindow] Custom strategy failed: " + e.getMessage());
            }
        }

        // 使用策略工厂
        if (screenshot instanceof BufferedImage) {
            return getStrategyFactory().selectAndExecuteStrategy(this, (BufferedImage) screenshot);
        }

        // 默认行为
        return createDefaultCommand();
    }

    /**
     * 创建默认指令
     */
    protected ICommand createDefaultCommand() {
        return new WaitCommand(this,3000);
    }

    /**
     * 停止自动化
     */
    public void stopAutomation() {
        automationRunning.set(false);
        automationEnabled = false;
        if (automationThread != null) {
            automationThread.interrupt();
        }
        System.out.println("[GameWindow] Automation stopped for: " + id);
    }


    /**
     * 检查自动化是否正在运行
     */
    public boolean isAutomationRunning() {
        return automationRunning.get();
    }

    /**
     * 获取自动化间隔
     */
    public long getAutomationInterval() {
        return automationIntervalMs;
    }

    /**
     * 设置自动化间隔（如果正在运行，需要重启生效）
     */
    public void setAutomationInterval(long intervalMs) {
        boolean wasRunning = isAutomationRunning();
        if (wasRunning) {
            stopAutomation();
        }

        this.automationIntervalMs = intervalMs;

        if (wasRunning) {
            startAutomationWithFactory(intervalMs);
        }
    }

    // ==================== 原有方法保持不变 ====================

    public void setCurrentSession(WindowSession session) {
        this.currentSession = session;
        if (session != null) {
            this.windowState = WindowState.UNOCCLUDED;
        } else {
            this.windowState = WindowState.OCCLUDED;
        }
    }

    public boolean isExecuting() {
        return currentSession != null && currentSession.isActive();
    }

    public void removeFromPool() {
        WindowPool.getInstance().removeWindow(this);
    }

    @Override
    public Rectangle getBounds() {
        if (currentSession != null && currentSession.getScreenWindow() != null) {
            return currentSession.getScreenWindow().getBounds();
        }
        return HwndUtil.getWindowRectangle(hwnd);
    }

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public boolean submitCommand(ICommand command) {
        if (command == null) {
            System.err.println("[GameWindow] Cannot submit null command");
            return false;
        }

        if (currentSession != null) {
            return currentSession.submitCommand(command);
        }

        WindowPool.getInstance().submitCommandTask(this, command);
        return true;
    }

    @Override
    public GameStatus getGameStatus() {
        return this.gameStatus;
    }

    @Override
    public WindowState getWindowState() {
        return this.windowState;
    }

    @Override
    public WinDef.HWND getHwnd() {
        return this.hwnd;
    }

    /**
     * 注册新策略到工厂
     */
    public void registerStrategy(IGameStrategy strategy) {
        getStrategyFactory().registerStrategy(strategy);
    }


    /**
     * 获取当前活动策略名称
     */
    public String getActiveStrategyName() {
        if (customAnalysisStrategy != null) {
            return "CustomStrategy";
        }
        return getStrategyFactory().getDefaultStrategy().getStrategyName();
    }
}